#!/usr/bin/python2.5
#
# (c) 2009 - Chip Turner
#
# Apache License, blah blah, it's a few hundred lines of python.

"""
There are two primary modes for %prog:

%prog -r REALM -g GUILD

The first mode prints all achievements for a player, completed or not.
The second mode is far more interesting.  It is designed to help
determine what sub-achievements are needed by guild members to reach
the specified ACHIEVEMENT.  It walks the guild roster (stopping at the
specified numeric maxrank), checking criteria for each member.  It
filters by level (default, only level 80) and allows multiple players
to be excluded via -x options, such as alts.
"""

import os
import time
import sys
import optparse
import textwrap

import armory_lib

def Score(ilvl):
  if ilvl < 186:
    return 3 * (ilvl - 200)
  if ilvl < 200:
    return 2 * (ilvl - 200)
  if ilvl < 231:
    return ilvl - 200

  return 1.10 * (ilvl - 200)

def main(args):
  parser = optparse.OptionParser(__doc__)
  parser.add_option("-r", "--realm", help="realm player or guild is on")
  parser.add_option("", "--eu", help="Use EU Armory instead of US armory",
                    action="store_true")
  parser.add_option("-g", "--guild", help="guild name to extract data for")
  parser.add_option("-c", "--character", help="only display this character in output")
  parser.add_option("-a", "--achievement", help="achievement to detail")
  parser.add_option("-m", "--maxrank", help="maximum rank to show results for (numeric, gm=0)", type=int)
  parser.add_option("-l", "--level", help="minimum level to show results for", type=int, default=80)
  parser.add_option("-x", "--exclude", help="exclude this user", action="append")

  options, args = parser.parse_args(args)

  if options.eu:
    armory_interface = armory_lib.ArmoryInterface("eu")
  else:
    armory_interface = armory_lib.ArmoryInterface("us")

  print "Report generated: %s" % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
  print

  # exclute tabards (slot 18) and shirts (slot 3)
  good_slots = set(range(0, 17))
  good_slots.remove(3)

  members = armory_interface.ParseRoster(options.realm, options.guild)
  matching_members = 0
  print "Player Gear:"
  for name, level, race_id, class_id, rank in members:
    if level < options.level: continue
    if options.character and options.character != name: continue
    if options.maxrank and rank > options.maxrank: continue
    if options.exclude and name in options.exclude: continue
    matching_members += 1

    ilvl_sum = 0
    slot_15_ilvl = 0
    saw_slot_16 = False
    output = list()
    char = armory_interface.ParseCharacter(options.realm, name)
    gear = char.Gear()
    for item in gear:
      if item.slot not in good_slots: continue
      pretty_gems = list()
      for gem_id in item.Gems():
        if gem_id > 0:
          gem_item = armory_interface.ItemInfo(gem_id)
          pretty_gems.append(gem_item["name"])
      if pretty_gems:
        gem_str = " (%s)" % (", ".join(pretty_gems))
      else:
        gem_str = ""

      item_info = armory_interface.ItemInfo(item.item_id)
      ilvl_sum += Score(item_info["ilvl"])

      # greatness is really good.
      if item.item_id in (44253, 44254, 44255, 42987):
        ilvl_sum -= Score(item_info["ilvl"])
        ilvl_sum += Score(226)
      # Handle two handed weapons... slot 15 empty means two hander.  Ugh.
      if item.slot == 15:
        slot_15_ilvl = item_info["ilvl"]
      if item.slot == 16 and item_info["ilvl"] >= 0:
        saw_slot_16 = True

      enchant_str = ""
      if item.enchant_id > 0:
        enchant_info = armory_interface.EnchantInfo(options.realm, name, item.slot, item.item_id, item.enchant_id)
        if enchant_info:
          enchant_str = " (%s)" % enchant_info["name"]

      output.append("  %s: %s (ilvl %d)%s%s" % (item.slot, item_info["name"], item_info["ilvl"], enchant_str, gem_str))
    if not saw_slot_16:
      ilvl_sum += Score(slot_15_ilvl)
    print "%s (Level %s, %s, rank %d, ilvl score: %.2f):" % (name, level, "/".join(char.Professions()), rank, ilvl_sum/len(good_slots))
    print "\n".join(output)
    print

if __name__ == '__main__':
  main(sys.argv[1:])
